// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

pub mod address;
pub mod config;
pub mod todo_list;

use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::sync::LazyLock;
use std::sync::Mutex;

use address::query_addr;
use config::config::AddressConfig;
use config::config::GlobalConfig;
use config::config::TodoListConfig;
use tauri::api::path::home_dir;
use tauri::{CustomMenuItem, Menu, Submenu};
use todo_list::query_todo_list;
use todo_list::todo_item::TodoItem;

use crate::address::add_addr::add_addr;
use crate::address::address::Address;
use crate::address::del_addr::del_addr;
use crate::address::edit_addr::edit_addr;
use crate::address::query_addr::{query_addr, query_by_id};
use todo_list::query_todo_list::query_todolist;

const CONFIG_FILE: &str = ".work-assist/config.toml";
static GLOBAL_CONFIG: LazyLock<Mutex<GlobalConfig>> =
    LazyLock::new(|| Mutex::new(GlobalConfig::new()));
static ADDRS: LazyLock<Mutex<HashMap<i64, Address>>> = LazyLock::new(|| Mutex::new(HashMap::new()));
static TODOLIST: LazyLock<Mutex<HashMap<usize, TodoItem>>> = LazyLock::new(|| Mutex::new(HashMap::new()));

fn main() -> Result<(), Box<dyn Error>> {
    // 初始化配置文件
    init_config().expect("初始化配置文件失败");

    // 初始化数据库
    let addr_tool = CustomMenuItem::new("addr_tool".to_string(), "通讯录");
    let todo_tool = CustomMenuItem::new("todo_tool", "代办");
    let db_tool = CustomMenuItem::new("db_tool", "数据库对比");
    let quit = CustomMenuItem::new("quit", "退出");
    let common_tool = Submenu::new(
        "通用工具",
        Menu::new()
            .add_item(addr_tool)
            .add_item(todo_tool)
            .add_item(db_tool)
            .add_item(quit),
    );

    let token = CustomMenuItem::new("token", "切换token");
    let t_esip_m = Submenu::new("T-ESIP-M", Menu::new().add_item(token));
    let menu = Menu::new().add_submenu(common_tool).add_submenu(t_esip_m);
    tauri::Builder::default()
        .menu(menu)
        .setup(|_app| {
            println!("启动");
            query_addr::load_all()?;
            query_todo_list::load_all()?;
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![
            add_addr,
            query_addr,
            del_addr,
            query_by_id,
            edit_addr,
            query_todolist
        ])
        .on_menu_event(|event| match event.menu_item_id() {
            "addr_tool" => {
                event.window().emit("menu-event", "addr_tool").unwrap();
            }
            "todo_tool" => {
                event.window().emit("menu-event", "todo_tool").unwrap();
            }
            "quit" => {
                std::process::exit(0);
            }
            _ => {}
        })
        .run(tauri::generate_context!())
        .expect("启动失败");
    Ok(())
}

fn init_config() -> Result<(), Box<dyn Error>> {
    let home_dir = home_dir().expect("用户目录不存在");
    let mut config_path = PathBuf::from(&home_dir);
    config_path.push(CONFIG_FILE);
    if let Some(parent) = config_path.parent() {
        if !parent.exists() {
            fs::create_dir_all(parent)?;
        }
    }
    if !config_path.exists() {
        let mut config_file = File::create(&config_path)?;
        let default_address_db_file = Path::new(&home_dir).join(".work-assist").join("address.db");
        let default_todolist_db_file = Path::new(&home_dir)
            .join(".work-assist")
            .join("todolist.db");
        let global_config = GlobalConfig {
            address: AddressConfig {
                db_file: default_address_db_file,
            },
            todo_list: TodoListConfig {
                db_file: default_todolist_db_file,
            },
        };
        let global_config_str = toml::to_string(&global_config).expect("序列化失败");
        config_file.write_all(global_config_str.as_bytes())?;
    }

    // 加载配置文件
    let config_content = fs::read_to_string(config_path)?;
    let config: GlobalConfig = toml::from_str(&config_content)?;
    println!("address config: {:#?}", config.address);
    GLOBAL_CONFIG.lock().unwrap().address = config.address;
    GLOBAL_CONFIG.lock().unwrap().todo_list = config.todo_list;
    Ok(())
}
